package top.honlnk.czuan.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.Digester;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import top.honlnk.czuan.common.constant.AutoLoginOptionConstant;
import top.honlnk.czuan.common.context.UserContextHolder;
import top.honlnk.czuan.common.exception.CustomException;
import top.honlnk.czuan.common.result.PageResult;
import top.honlnk.czuan.common.utils.BitmaskUtil;
import top.honlnk.czuan.common.utils.JWTTokenUtil;
import top.honlnk.czuan.common.utils.SnowflakeIdUtil;
import top.honlnk.czuan.mapper.UserMapper;
import top.honlnk.czuan.pojo.dto.AddUserDTO;
import top.honlnk.czuan.pojo.dto.LoginDTO;
import top.honlnk.czuan.pojo.dto.PageGetUserDTO;
import top.honlnk.czuan.pojo.entity.User;
import top.honlnk.czuan.pojo.vo.GetUserInfoVO;
import top.honlnk.czuan.pojo.vo.LoginVO;
import top.honlnk.czuan.service.UserService;

import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BitmaskUtil bitmaskUtil;

    @Autowired
    private SnowflakeIdUtil snowflakeIdUtil;
    // 生成唯一id值
    private Integer makeOnlyId() {
        return snowflakeIdUtil.nextId();
    }

    @Override
    public void addUser(@NotNull AddUserDTO addUserDTO) {
        String password = addUserDTO.getPassword();
        Digester digester = DigestUtil.digester("sm3");
        String passwordSM3 = digester.digestHex(password);
        User user = User.builder()
                .id(makeOnlyId())
                .account(addUserDTO.getAccount())
                .uname(addUserDTO.getUname())
                .password(passwordSM3)
                .mail(addUserDTO.getMail())
                .build();

        // 从ThreadLocal中获取当前操作用户的信息
        User currentUser = UserContextHolder.getUser();
        if (currentUser != null) {
            user.setCreatedBy(currentUser.getAccount());
            user.setUpdateBy(currentUser.getAccount());
        } else {
            // 如果没有找到当前用户，则使用默认值"system"
            user.setCreatedBy("system");
            user.setUpdateBy("system");
        }
        if (!addUserDTO.getPowerList().isEmpty()) {
            user.setPower(bitmaskUtil.combinePermissions(addUserDTO.getPowerList()));
        }
        userMapper.addUser(user);

        log.info("添加用户成功");
    }
    @Override
    public LoginVO login(@NotNull LoginDTO loginDTO) {
        String account = loginDTO.getAccount();
        String password = loginDTO.getPassword();

        int days = switch (loginDTO.getAutoLoginOption()) {
            case AutoLoginOptionConstant.NOT_AUTO_LOGIN -> 0;
            case AutoLoginOptionConstant.ONE_WEEK -> 7;
            case AutoLoginOptionConstant.ONE_MONTH -> 30;
            case AutoLoginOptionConstant.ONE_YEAR -> 365;
            default -> throw new CustomException("自动登录选项无效");
        };

        Digester digester = DigestUtil.digester("sm3");
        String passwordSM3 = digester.digestHex(password);

        User user = userMapper.getUserByAccount(account);
        if (user == null) {
            throw new CustomException("账号不存在");
        }
        if (!user.getPassword().equals(passwordSM3)) {
            throw new CustomException("密码错误");
        }

        String token = JWTTokenUtil.genToken(user, days);
        log.info("登录生成token: {}", token);

        return LoginVO.builder()
                .account(user.getAccount())
                .uname(user.getUname())
                .eMail(user.getMail())
                .token(token)
                .build();

    }

    @Override
    @Cacheable(value = "userLoginCache", key = "#id")
    public User getUserById(Integer id) {
        return userMapper.getUserById(id);
    }

    @Override
    public User getUserByAccount(String account) {
        User user = userMapper.getUserByAccount(account);
        log.info("根据账号查询到的用户信息: {}", user);
        User currentUser = UserContextHolder.getUser();
        log.info("当前用户信息: {}", currentUser);
        return user;
    }

    @Override
    public PageResult getUser(PageGetUserDTO pageGetUserDTO) {
        log.info("查询用户信息，参数为: {}", pageGetUserDTO);

        if (pageGetUserDTO.getPage() == 0 || pageGetUserDTO.getSize() == 0) {
            throw new CustomException("page或size为必选参数且值不能为0"); // page与size这两个参数不允许为0
        }

        PageHelper.startPage(pageGetUserDTO.getPage(), pageGetUserDTO.getSize());
        Page<User> user = userMapper.getUser(pageGetUserDTO);
        long total = user.getTotal();
        List<User> records = user.getResult();
        List<GetUserInfoVO> getUserInfoVOList = records.stream().map(item -> GetUserInfoVO.builder()
                .account(item.getAccount())
                .uname(item.getUname())
                .eMail(item.getMail())
                .createdAt(item.getCreatedAt())
                .createdBy(item.getCreatedBy())
                .build()).toList();
        return new PageResult(total, getUserInfoVOList);
    }
}
